package nachos.network;
import nachos.machine.*;
import nachos.threads.*;
import nachos.userprog.*;
import nachos.vm.*;
import nachos.network.*;
/**
 * A kernel with network support.
 */
public class NetKernel extends UserKernel {
	/**
	 * Allocate a new networking kernel.
	 */
	public NetKernel(){

		super();
		System.out.println("Shit Made!");
	}
	/**
	 * Initialize this kernel.
	 */
	public void initialize(String[] args){
		super.initialize(args);

		postOffice = new PostOffice();
	}
	/**
	 * Test the network. Create a server thread that listens for pings on port
	 * 1 and sends replies. Then ping one or two hosts. Note that this test
	 * assumes that the network is reliable (i.e. that the network's
	 * reliability is 1.0).
	 */
	public void selfTest(){
		System.out.println("Fuck my life");


		System.out.println("sleep");
		timeout();
		System.out.println("wake");

		final KThread test2 = new KThread(new Runnable() {
			public void run(){
				socketTest2();
			}
		});
		KThread test1 = new KThread(new Runnable() {
			public void run(){
				socketTest(test2);
			}
		});

		test1.fork();
		test2.fork();

		KThread.yield();

	}
	private void socketTest(KThread thr){
		NetSocket scktSnd = new NetSocket(1);
		System.out.println("shit 1 made");
		if(!scktSnd.connect(Machine.networkLink().getLinkAddress(), 2)){
			return;
		}
		byte[] bt = new byte["Hi There".length()];
		String str = "Hi There";
		System.out.println("Wrote "
			+ scktSnd.write(str.getBytes(), 0, str.length())
			+ " bytes");
		thr.join();
		KThread.yield();
		scktSnd.close();
	}
	private void socketTest2(){
		NetSocket scktRcv = new NetSocket(2);
		System.out.println("shit 2 made");
		scktRcv.accept(2);
		byte[] bt = new byte["Hi There".length()];
		KThread.yield();
		timeout();
		timeout();
		System.out.println("read "
			+ scktRcv.read(bt, 0, bt.length)
			+ " bytes");
		System.out.println(new String(bt));
	}
	/**
	 * Start running user programs.
	 */
	public void run(){
		super.run();
	}
	/**
	 * Terminate this kernel. Never returns.
	 */
	public void terminate(){
		super.terminate();
	}
	public static void timeout(){
		alarm.waitUntil(timeoutLength);
	}
	static public PostOffice postOffice;
	private static Alarm alm = new Alarm();
	public static final int timeoutLength = 1000;
	public static final int maxTimeout = 3;
	// dummy variables to make javac smarter
	private static NetProcess dummy1 = null;
}
